home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / utilitys / 81 / colrtrix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-09-03  |  20.5 KB  |  587 lines

  1. /* -------------------------------------------------------------------- */
  2. /* COLRTRIX.C                "Color Trix"                               */
  3. /* David Jarvis, 1987                                   Version 041787  */
  4. /*                                                                      */
  5. /* Developed with Lattice C                                             */
  6. /*                                                                      */
  7. /* Contains and demonstrates the following functions for the Atari ST:  */
  8. /*    fade_to_black()      Fades from the current palette to black      */
  9. /*    fade_from_black()    Fades from black to the desired palette      */
  10. /*    gradually_change_colors()    Causes a gradual palette change      */
  11. /*    flash_colors()       Causes screen to 'flash' certain # of times  */
  12. /*    load_neo()           Loads a NEOCHROME picture into a buffer      */
  13. /*                                                                      */
  14. /* These functions will work in any (current) ST resolution.  This demo */
  15. /* is limited to low resolution because it uses NEOCHROME pictures to   */
  16. /* illustrate the effects.                                              */
  17. /*                                                                      */
  18. /* Programmers may use any of these functions in their own programs     */
  19. /* without incurring the slightest obligation, legal, moral or          */
  20. /* otherwise.                                                           */
  21. /* -------------------------------------------------------------------- */
  22.  
  23. #include <stdio.h>                  /* standard I/O definitions         */
  24. #include <osbind.h>                 /* Operating system bindings        */
  25. #include <fcntl.h>                  /* File control                     */
  26. #include <gemlib.h>                 /* VDI and AES definitions          */
  27. #include <portab.h>                 /* Portable storage definitions     */
  28.  
  29. /* -------- keyboard definitions (scan codes) ------------------------- */
  30.  
  31. #define HELP       0x00620000
  32. #define UNDO       0x00610000
  33. #define F01        0x003b0000
  34. #define F02        0x003c0000
  35. #define F03        0x003d0000
  36. #define F04        0x003e0000
  37. #define F05        0x003f0000
  38. #define F06        0x00400000
  39. #define F07        0x00410000
  40. #define F08        0x00420000
  41. #define F09        0x00430000
  42. #define F10        0x00440000
  43.  
  44. /* ------- variable declarations ------------------------------------- */
  45.  
  46. /* Form_alert() and v_gtext() strings */
  47. BYTE title[] = "[1][      COLRTRIX       |-- David T. Jarvis, 1987 --][  OK  ]";
  48. BYTE sorry[] =
  49.   "[3][  Sorry ...  | Use COLRTRIX in Low Resolution Only ][ @^!!?#* ]";
  50. BYTE err001[] = "[1][COLRTRIX Error 01:|Error opening File.][ OK ]";
  51. BYTE err002[] = "[1][COLRTRIX Error 02:|File was too small.][ OK ]";
  52. BYTE err999[] =
  53.    "[1][COLRTRIX Error 99:|Unknown error in loading.][ OK ]";
  54. BYTE uprompt1[ 256 ], uprompt2[ 256 ];
  55.  
  56. /* Character variables for file handling */
  57. BYTE  filespec[65],
  58.       currpath[65],
  59.       filename[15];
  60.  
  61. /* Pointer to base of screen buffer */
  62. BYTE *pbase;
  63. /* Picture buffers */
  64. BYTE buff1[ 32000 ], buff2[ 32000 ];
  65.  
  66. /* GEM variables */
  67. WORD  contrl[12],      intin[128],
  68.       ptsin[128],      intout[128],
  69.       ptsout[128],     work_in[11],
  70.       work_out[57],    pxyarray[10],
  71.       handle;
  72.  
  73. /* Miscellanous variables */
  74. WORD  pal1[ 16 ], pal2[ 16 ], oldpal[ 16 ], *curpal;
  75. LONG longch;
  76.  
  77. /* ------ function declarations ----------------------------------- */
  78.  
  79. BYTE  *strcat(),
  80.       *strcpy(),
  81.       *fgets();
  82. WORD load_neo();
  83. void getpic();
  84. void work_init(), cls_without_mess(), clean_up(), help();
  85. void fade_to_black(), fade_from_black();
  86. void gradually_change_colors(), flash_colors(), screen_load();
  87.  
  88. /* --------- Main program ------------------------------------------ */
  89.  
  90. main()
  91. {
  92. WORD i, drive;
  93.  
  94. /* Initialize the workstation */
  95.    work_init();
  96.  
  97. /* Obtain some information about the system */
  98.    if (Getrez())
  99.       {
  100.       form_alert( 1,sorry );
  101.       appl_exit();
  102.       exit();
  103.       }
  104.    pbase = (BYTE *)Physbase();
  105.    for (i=0; i<16; i++)
  106.       oldpal[ i ] = Setcolor(i,-1);
  107.  
  108. /* Initialize form_alert strings for prompting user */
  109.    strcpy( uprompt1,"[1][ You will be prompted to  |" );
  110.    strcat( uprompt1,    " Load NEO Picture 1.  It  |" );
  111.    strcat( uprompt1,    " will be used to          |" );
  112.    strcat( uprompt1,    " demonstrate the graphics |" );
  113.    strcat( uprompt1,    " functions in COLRTRIX.   ][ okay ]" );
  114.    strcpy( uprompt2,"[1][ Now select NEO Picture 2.|" );
  115.    strcat( uprompt2,    " Only the Palette for it  |" );
  116.    strcat( uprompt2,    " will be used -- it should|" );
  117.    strcat( uprompt2,    " differ from that of      |" );
  118.    strcat( uprompt2,    " Picture 1.               ][ okay ]" );
  119.  
  120. /* Initialize filename,path and drive information */
  121.    strcpy( currpath,"?:" );
  122.    drive = Dgetdrv();
  123.    currpath[0] = 'A'+drive;
  124.    Dgetpath(&currpath[2],drive+1);
  125.    strcat(currpath,"\\*.NEO");
  126.  
  127. /* Clear the screen and get started */
  128.    cls_without_mess();
  129.    form_alert(1,title);
  130.  
  131. /* Prompt for the first picture and load it */
  132.    getpic( uprompt1,buff1,pal1,0 );
  133.    curpal = (WORD *)pal1;
  134.  
  135. /* Prompt for and load second picture */
  136.    getpic( uprompt2,buff2,pal2,0 );
  137.  
  138. /* Give instructions...then handle all subsequent input */
  139.    help();
  140.    Setpallete( pal1 );
  141.    screen_load( buff1 );
  142.    do {
  143.       if (Bconstat(2))
  144.          {
  145.          longch = Bconin(2);     /* use the LONG value to get scan codes */
  146.          switch( longch )
  147.             {
  148.             case HELP:           help();
  149.                                  screen_load( buff1 );
  150.                                  break;
  151.             case UNDO:           screen_load( buff1 );
  152.                                  Setpallete( pal1 );
  153.                                  curpal = (WORD *)pal1;
  154.                                  break;
  155.             case F01:            fade_from_black( pal1,16,3 );
  156.                                  curpal = (WORD *)pal1;
  157.                                  break;
  158.             case F02:            fade_from_black( pal2,16,3 );
  159.                                  curpal = (WORD *)pal2;
  160.                                  break;
  161.             case F03:            fade_to_black( curpal,16,3 );
  162.                                  break;
  163.             case F04:            if (curpal == pal1)
  164.                                     {
  165.                                     gradually_change_colors( pal1,pal2,16,3 );
  166.                                     curpal = (WORD *)pal2;
  167.                                     }
  168.                                  else
  169.                                     {
  170.                                     gradually_change_colors( pal2,pal1,16,3 );
  171.                                     curpal = (WORD *)pal1;
  172.                                     }
  173.                                  break;
  174.             case F05:            flash_colors( curpal,16,8,5 );
  175.                                  break;
  176.             case F06:            getpic( uprompt1,buff1,pal1,1 );
  177.                                  screen_load( buff1 );
  178.                                  curpal = (WORD *)pal1;
  179.                                  break;
  180.             case F07:            getpic( uprompt2,buff2,pal2,0 );
  181.                                  screen_load( buff1 );
  182.                                  break;
  183.             case F08:            graf_mouse( M_OFF,0L );
  184.                                  for (i=0; i<32000; i++)
  185.                                     buff1[ i ] = buff2[ i ];
  186.                                  for (i=0; i<32000; i++)
  187.                                     buff2[ i ] = pbase[ i ];
  188.                                  graf_mouse( M_ON,0L );
  189.                                  screen_load( buff1 );
  190.                                  break;
  191.             case F09:            fade_from_black( pal1,16,16 );
  192.                                  curpal = (WORD *)pal1;
  193.                                  break;
  194.             case F10:            fade_to_black( curpal,16,2 );
  195.                                  v_clrwk( handle );
  196.                                  clean_up();
  197.                                  exit();
  198.                                  break;
  199.             default:             break;
  200.             }
  201.          }  /* if Bconstat(2) */
  202.       } while (1);      /* for a very, very long time... */
  203. }
  204.  
  205. /* -------- Additional functions ----------------------------------- */
  206.  
  207. /* work_init() initializes the workstation */
  208. void work_init()
  209. {
  210. WORD i;
  211.  
  212.    appl_init();
  213.    for( i = 0; i<10; work_in[ i++ ]=1 );
  214.    work_in[10] = 2;
  215.    v_opnvwk( work_in, &handle, work_out );
  216. }
  217.  
  218. /* cls_without_mess() clears the screen without that nagging mouse block */
  219. void cls_without_mess()
  220. {
  221.    graf_mouse(M_OFF,0L);
  222.    v_clrwk( handle );
  223.    graf_mouse(M_ON,0L);
  224. }
  225.  
  226. /* clean_up() puts everything away before going home */
  227. void clean_up()
  228. {
  229.    Setpallete( oldpal );
  230.    appl_exit();
  231. }
  232.  
  233. /* getpic() gets a NEO file...it prompts the user, calls load_neo(),    */
  234. /* handles errors returned by that function                             */
  235. void getpic( prompt,where,pal,loadcolors )
  236. BYTE *prompt, *where;
  237. WORD *pal, loadcolors;
  238. {
  239. WORD err_ret, fs_exit;
  240. LONG i;
  241.  
  242. /* Get the picture file name */
  243.    form_alert(1,prompt);
  244.    fsel_input(currpath,filename,&fs_exit);
  245.    if (!fs_exit)
  246.       {
  247.       clean_up();
  248.       exit();
  249.       }
  250.    else
  251.       {
  252.       strcpy(filespec,currpath);
  253.       i = strlen(filespec)-1;
  254.       while ( (i) && (filespec[ i ] != '\\') && (filespec[ i ] != ':'))
  255.          i--;
  256.       if (i)
  257.          filespec[ i+1 ] = '\0';
  258.       else
  259.          filespec[ 0 ] = '\0';
  260.       strcat(filespec,filename);
  261.       graf_mouse(M_OFF,0L);
  262.       err_ret = load_neo(filespec,where,pal,loadcolors);
  263.       graf_mouse(M_ON,0L);
  264.       switch(err_ret)
  265.          {
  266.          case 0:  break;
  267.          case -1: form_alert(1,err001);
  268.                   break;
  269.          case -2: form_alert(1,err002);
  270.                   break;
  271.          default: form_alert(1,err999);
  272.                   break;
  273.          }
  274.       }
  275. }
  276.  
  277. /* ----------------------------------------------------------------- */
  278. /* load_neo()  -- load a NEOCHROME picture file into memory          */
  279. /* Type:                                                             */
  280. /*    WORD     -- Returns: 0 if successful                           */
  281. /*             --          -1 if file could not be opened            */
  282. /*             --          -2 if file was too small (<32128 bytes)   */
  283. /* Parameters:                                                       */
  284. /*    filespec -- pointer to character string containing file name   */
  285. /*    where    -- address of buffer to copy picture into             */
  286. /*    pal      -- address of WORD array to copy pic's palette into   */
  287. /*    loadcolors -- 1 if screen colors should be changed to palette  */
  288. /* ----------------------------------------------------------------- */
  289. WORD load_neo(filespec,where,pal,loadcolors)
  290. BYTE *filespec, *where;
  291. WORD *pal, loadcolors;
  292. {
  293. BYTE buffer[ 256 ];
  294. WORD nrez;
  295. LONG fhandle, ret;
  296.  
  297. if ((fhandle = open(filespec,O_RDONLY | O_RAW)) < 0)
  298.    return(-1);
  299. if ((ret = read(fhandle,&nrez,4L)) != 4L)
  300.    return(-2);
  301. if ((ret = read(fhandle,pal,32L)) != 32L)
  302.    return(-2);
  303. if ((ret = read(fhandle,buffer,92L)) != 92L)
  304.    return(-2);
  305. if (loadcolors)
  306.    Setpallete(pal);
  307. if ((ret = read(fhandle,where,32000L)) != 32000L)
  308.    return(-2);
  309. close(fhandle);
  310. return(0);
  311. }
  312.  
  313. /* screen_load() transfers the contents of a buffer onto the screen   */
  314. /* Note that it uses the global variable pbase, which should point to */
  315. /* the base of screen memory                                          */
  316. void screen_load( buffer )
  317. BYTE *buffer;
  318. {
  319. WORD i;
  320.  
  321.    graf_mouse( M_OFF,0L );
  322.    for (i=0; i<32000; i++)
  323.       pbase[ i ] = buffer[ i ];
  324.    graf_mouse( M_ON,0L );
  325. }
  326.  
  327. /* ----------------------------------------------------------------------- */
  328. /* Fade_to_black() gradually changes the indicated number of screen colors */
  329. /* to blackness                                                            */
  330. /* Parameters:                                                             */
  331. /*    pal         Pointer to 16 WORDs containing palette to start with     */
  332. /*    numcolors   Changes only the first 'numcolors' colors                */
  333. /*    dfact       Delay factor -- a value of 4 produces a smooth fade with */
  334. /*                   16 colors;  higher numbers produce a slower fade      */
  335. /* ----------------------------------------------------------------------- */
  336. void fade_to_black( pal,numcolors,dfact )
  337. WORD pal[], numcolors, dfact;
  338. {
  339. WORD tempal[ 16 ];
  340. WORD i, done=1, place1, place2, place3;
  341. LONG j;
  342.  
  343. /* Start with current palette */
  344. Setpallete( pal );
  345. for (i=0; i<16; i++)
  346.    tempal[ i ] = pal[ i ];
  347.  
  348. /* Gradually darken colors until all are black (000) */
  349. do
  350.    {
  351.    done = 1;
  352.    for (i=0; i<numcolors; i++)
  353.       {
  354.       place1 = (WORD)(tempal[ i ]/256) * 256;
  355.       place2 = (WORD)((tempal[ i ]-place1)/16) * 16;
  356.       place3 = tempal[ i ] - (place1 + place2);
  357.       if (place1 > 0)
  358.          {
  359.          tempal[ i ] -= 256;
  360.          done = 0;
  361.          }
  362.       if (place2 > 0)
  363.          {
  364.          tempal[ i ] -= 16;
  365.          done = 0;
  366.          }
  367.       if (place3 > 0)
  368.          {
  369.          tempal[ i ] --;
  370.          done = 0;
  371.          }
  372.       /* delay for a few microseconds */
  373.       for (j=0L; j<100L*dfact; j++)
  374.          ;
  375.       }
  376.    /* At each change, install the new colors */
  377.    if (!done)
  378.       Setpallete( tempal );
  379.    } while (!done);
  380. }
  381.  
  382. /* ----------------------------------------------------------------------- */
  383. /* Fade_from_black() sets all colors to black, then gradually brightens    */
  384. /* the indicated number of screen colors until they match the desired      */
  385. /* palette                                                                 */
  386. /*    newpal      Pointer to 16 WORDs containing desired color palette     */
  387. /*    numcolors   Fades to only the first 'numcolors' colors               */
  388. /*    dfact       Delay factor -- a value of 4 produces a smooth fade with */
  389. /*                   16 colors; larger numbers produce slower fades        */
  390. /* ----------------------------------------------------------------------- */
  391. void fade_from_black( newpal,numcolors,dfact )
  392. WORD newpal[], numcolors, dfact;
  393. {
  394. WORD tempal[ 16 ];
  395. WORD i, done=1, new1, new2, new3, temp1, temp2;
  396. LONG j;
  397.  
  398. /* Start with the first numcolors completely black */
  399. for (i=0; i<16; i++)
  400.    if (i<numcolors)
  401.       tempal[ i ] = 0;
  402.    else
  403.       tempal[ i ] = newpal[ i ];
  404. Setpallete( tempal );
  405.  
  406. /* Gradually brighten colors until all match appropriate values */
  407. do
  408.    {
  409.    done = 1;
  410.    for (i=0; i<numcolors; i++)
  411.       {
  412.       new1 = (WORD)(newpal[ i ]/256) * 256;
  413.       if (tempal[ i ] < new1)
  414.          {
  415.          tempal[ i ] += 256;
  416.          done = 0;
  417.          }
  418.       temp1 = (WORD)(tempal[ i ]/256) * 256;
  419.       new2 = (WORD)((newpal[ i ]-new1)/16) * 16;
  420.       if (tempal[ i ]-temp1 < new2)
  421.          {
  422.          tempal[ i ] += 16;
  423.          done = 0;
  424.          temp2 = (WORD)((tempal[ i ]-temp1)/16) * 16;
  425.          }
  426.       temp2 = (WORD)((tempal[ i ]-temp1)/16) * 16;
  427.       new3 = newpal[ i ] - (new1+new2);
  428.       if (tempal[ i ]-(temp1+temp2) < new3)
  429.          {
  430.          tempal[ i ] ++;
  431.          done = 0;
  432.          }
  433.       /* delay for a few microseconds */
  434.       for (j=0L; j<100L*dfact; j++)
  435.          ;
  436.       }
  437.    /* At each change, install the new colors */
  438.    if (!done)
  439.       Setpallete( tempal );
  440.    } while (!done);
  441. Setpallete( newpal );
  442. }
  443.  
  444. /* ----------------------------------------------------------------------- */
  445. /* Gradually_change_colors() fades from one palette to another             */
  446. /* Parameters:                                                             */
  447. /*    oldpal      Pointer to 16 WORDs containing first color palette       */
  448. /*    newpal      Pointer to 16 WORDs containing second color palette      */
  449. /*    numcolors   Changes only the first 'numcolors' colors                */
  450. /*    dfact       Delay factor -- a value of 4 produces a smooth change    */
  451. /*                   with 16 colors;  larger numbers produce slower change */
  452. /* ----------------------------------------------------------------------- */
  453. void gradually_change_colors( oldpal,newpal,numcolors,dfact )
  454. WORD oldpal[], newpal[], numcolors, dfact;
  455. {
  456. WORD tempal[ 16 ];
  457. WORD place1, place2, place3, oplace1, oplace2, oplace3;
  458. WORD i, done=1;
  459. LONG j;
  460.  
  461. /* Start with palette 1 */
  462. Setpallete( oldpal );
  463. for (i=0; i<16; i++)
  464.    tempal[ i ] = oldpal[ i ];
  465.  
  466. /* Gradually alter temporary palette values until they match the new ones */
  467. do
  468.    {
  469.    done = 1;
  470.    for (i=0; i<numcolors; i++)
  471.       {
  472.       place1  = (WORD)(newpal[ i ]/256) * 256;
  473.       oplace1 = (WORD)(tempal[ i ]/256) * 256;
  474.       place2  = (WORD)((newpal[ i ]-place1)/16) * 16;
  475.       oplace2 = (WORD)((tempal[ i ]-oplace1)/16) * 16;
  476.       place3  = newpal[ i ] - (place1+place2);
  477.       oplace3 = tempal[ i ] - (oplace1+oplace2);
  478.       if (oplace1 < place1)
  479.          {
  480.          tempal[ i ] += 256;
  481.          done = 0;
  482.          }
  483.       else
  484.          if (oplace1 > place1)
  485.             {
  486.             tempal[ i ] -= 256;
  487.             done = 0;
  488.             }
  489.       if (oplace2 < place2)
  490.          {
  491.          tempal[ i ] += 16;
  492.          done = 0;
  493.          }
  494.       else
  495.          if (oplace2 > place2)
  496.             {
  497.             tempal[ i ] -= 16;
  498.             done = 0;
  499.             }
  500.       if (oplace3 < place3)
  501.          {
  502.          tempal[ i ] ++;
  503.          done = 0;
  504.          }
  505.       else
  506.          if (oplace3 > place3)
  507.             {
  508.             tempal[ i ] --;
  509.             done = 0;
  510.             }
  511.       /* delay for a few microseconds */
  512.       for (j=0L; j<100L*dfact; j++)
  513.          ;
  514.       }
  515.    /* At each change, install the new colors */
  516.    if (!done)
  517.       Setpallete( tempal );
  518.    } while (!done);
  519. Setpallete( newpal );
  520. }
  521.  
  522. /* ----------------------------------------------------------------------- */
  523. /* flash_colors() causes on-screen colors to briefly appear 'negative'     */
  524. /* an indicated number of times.  Useful for effects such as explosions... */
  525. /* Parameters:                                                             */
  526. /*    pal               Pointer to 16 WORDs containing palette values      */
  527. /*    numcolors         Number of colors to change during flash operation  */
  528. /*    dfact             Delay factor -- 8 or so produces quick flashes     */
  529. /*    times             Number of times to flash                           */
  530. /* ----------------------------------------------------------------------- */
  531. void flash_colors( pal,numcolors,dfact,times )
  532. WORD pal[], numcolors, dfact, times;
  533. {
  534. WORD tempal[ 16 ];
  535. WORD i, place1, place2, place3;
  536. LONG j;
  537.  
  538. /* Build palette of colors to 'flash' to */
  539. for (i=0; i<16; i++)
  540.    if (i >= numcolors)           /* If outside numcolors, use same color */
  541.       tempal[ i ] = pal[ i ];
  542.    else                          /* otherwise, use 'opposite' */
  543.       {
  544.       place1 = (WORD)(pal[ i ]/256) * 256;
  545.       tempal[ i ] = (7*256-place1)*256;
  546.       place2 = (WORD)((pal[ i ] - (place1*256))/16) * 16;
  547.       tempal[ i ] += (7*16-place2)*16;
  548.       place3 = pal[ i ] - ((place1*256) + (place2*16));
  549.       tempal[ i ] += (7-place3);
  550.       }
  551.  
  552. /* Now, flash the user */
  553. for (i=0; i<times; i++)
  554.    {
  555.    Setpallete( tempal );
  556.    for (j=0L; j<250L*dfact; j++)
  557.       ;
  558.    Setpallete( pal );
  559.    for (j=0L; j<250L*dfact; j++)
  560.       ;
  561.    }
  562. }
  563.  
  564. /* Help() displays instructions about COLRTRIX */
  565. void help()
  566. {
  567.    graf_mouse( M_OFF,0L );
  568.    v_clrwk( handle );
  569.    v_gtext( handle,1,8*1, "Key          COLRTRIX Commands" );
  570.    v_gtext( handle,1,8*2, "---------------------------------------" );
  571.    v_gtext( handle,1,8*3, "HELP    Print These Instructions" );
  572.    v_gtext( handle,1,8*4, "UNDO    Display Picture 1, Palette 1" );
  573.    v_gtext( handle,1,8*5, "F1      Fade In (to Palette 1)" );
  574.    v_gtext( handle,1,8*6, "F2      Fade In (to Palette 2)" );
  575.    v_gtext( handle,1,8*7, "F3      Fade Out" );
  576.    v_gtext( handle,1,8*8, "F4      Gradual Palette Change" );
  577.    v_gtext( handle,1,8*9, "F5      Color Flash" );
  578.    v_gtext( handle,1,8*10,"F6      Re-Load Picture 1" );
  579.    v_gtext( handle,1,8*11,"F7      Re-Load Picture 2" );
  580.    v_gtext( handle,1,8*12,"F8      Switch Pictures" );
  581.    v_gtext( handle,1,8*13,"F9      Slow Fade In (to Palette 1)" );
  582.    v_gtext( handle,1,8*14,"F10     Exit" );
  583.    v_gtext( handle,20,8*16,"Press any key to continue..." );
  584.    getch();
  585.    graf_mouse( M_ON,0L );
  586. }
  587.